/*
 *    Copyright 2008-2009 The Digester Tools Team
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
package com.digestertools.annotations.dbinsert;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

import lombok.Getter;
import lombok.Setter;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.digestertools.annotations.ObjectCreate;
import com.digestertools.annotations.SetNext;
import com.digestertools.annotations.SetProperty;

/**
 * 
 * @author Simone Tripodi
 * @version $Id: DatabaseConnector.java 357 2009-12-16 20:00:36Z simone.tripodi $
 */
@ObjectCreate(pattern = "database")
public final class DatabaseConnector {

    private final Log log = LogFactory.getLog(getClass());

    private final Connection connection;

    @Getter
    private int insertedRow = 0;

    @SetProperty(
            pattern = "database/table",
            attributeName = "name"
    )
    @Setter
    private String tablePtr;

    public DatabaseConnector() {
        try {
            File tmp = File.createTempFile("dbTEST", "dat");
            tmp.delete();

            String connectionURL = "jdbc:derby:"
                + tmp.getAbsolutePath()
                + ";create=true";

            if (this.log.isDebugEnabled()) {
                this.log.debug("Connecting to db ["
                        + connectionURL
                        + "]");
            }

            Class.forName("org.apache.derby.jdbc.EmbeddedDriver");

            this.connection = DriverManager.getConnection(connectionURL);

            Statement statement = this.connection.createStatement();
            statement.execute("CREATE TABLE muppets (name VARCHAR(26), colour VARCHAR(26), hobby VARCHAR(26))");
            statement.execute("CREATE TABLE things (name VARCHAR(26), owner VARCHAR(26))");
            statement.close();
        } catch (Exception e) {
            if (this.log.isErrorEnabled()) {
                this.log.error("Impossible to initialize the db", e);
            }
            throw new RuntimeException("Impossible to create the db");
        }
    }

    @SetNext
    public void storeRow(Row row) {
        StringBuffer colnames = new StringBuffer();
        StringBuffer colvalues = new StringBuffer();

        for (Column column : row.getColumns()) {
            if (colnames.length() > 0) {
                colnames.append(", ");
                colvalues.append(", ");
            }

            colnames.append(column.getName());

            colvalues.append("'");
            colvalues.append(column.getValue());
            colvalues.append("'");
        }

        StringBuffer buf = new StringBuffer();
        buf.append("INSERT INTO ");
        buf.append(this.tablePtr);
        buf.append(" (");
        buf.append(colnames.toString());
        buf.append(") VALUES (");
        buf.append(colvalues.toString());
        buf.append(")");

        String statementString = buf.toString();

        if (this.log.isDebugEnabled()) {
            this.log.debug("Executing statement ["
                        + statementString
                        + "]");
        }

        try {
            Statement statement = this.connection.createStatement();
            statement.execute(statementString);
            statement.close();

            this.insertedRow++;
        } catch (SQLException e) {
            if (this.log.isErrorEnabled()) {
                this.log.error("Impossible to execute statement ["
                        + statementString
                        + "]", e);
            }
        }
    }

}
